package com.last.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.last.entity.Order;
import com.last.entity.Result;
import com.last.entity.RoomInfo;
import com.last.interceper.gainUserId;
import com.last.mapper.OrderMapper;
import com.last.mapper.RoomMapper;
import com.last.order.IdWorker;
import com.last.service.IOrderService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

@Service
public class OrderService extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private RoomMapper roomMapper;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    @Transactional
    public Result<Order> saveOrder(Order order) {

        if(order == null){
            return new Result<>(false,"参数不合法");
        }
        if (StringUtils.isEmpty(gainUserId.getUserInfo())){
            return new Result<>(false,"未登录");
        }
        String userId = gainUserId.getUserInfo();
        order.setUserId(Integer.valueOf(userId));

        RLock lock = redissonClient.getLock("roomLock:"+order.getRoomId());
        lock.lock(10, TimeUnit.SECONDS);

//        Boolean lock = stringRedisTemplate.boundValueOps("roomLock:"+order.getRoomId()).setIfAbsent("xxx");
//
//        while (!lock){
//            lock = stringRedisTemplate.boundValueOps("roomLock:"+order.getRoomId()).setIfAbsent("xxx");
//        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        long start = Long.parseLong(simpleDateFormat.format(order.getStartDate()));
        long end = Long.parseLong(simpleDateFormat.format(order.getLeaveDate()));

        AtomicReference<Boolean> hasLock = new AtomicReference<>(true);

        BoundHashOperations<String, String, String> stringObjectObjectBoundHashOperations = stringRedisTemplate.boundHashOps("roomId:" + order.getRoomId());
        //String s = stringRedisTemplate.boundValueOps("roomId:s" + order.getRoomId()).get();
        //StringBuffer sb;
        Objects.requireNonNull(stringObjectObjectBoundHashOperations.keys()).forEach(v->{
            if(start<=Long.parseLong(v)){
                if(end>=Long.parseLong(v)){
                    hasLock.set(false);
                }
            }
            if(start<=Long.parseLong(Objects.requireNonNull(stringObjectObjectBoundHashOperations.get(v)))){
                if(end>=Long.parseLong(Objects.requireNonNull(stringObjectObjectBoundHashOperations.get(v))))
                    hasLock.set(false);
            }
        });

        if(hasLock.get()){
            //BoundHashOperations<String, String, String> stringObjectObjectBoundHashOperations = stringRedisTemplate.boundHashOps("roomId:" + order.getRoomId());

            order.setOrderId(idWorker.nextId()+"");
            order.setOrderStatus(0);
            order.setUpdateTime(new Date());
            order.setOrderTime(new Date());

            //查寻room（room_info->price）对应价格，订单表格添加价格字段
            //向order添加对应对应价格

            RoomInfo roomInfo = roomMapper.selectById(order.getRoomId());
            order.setOrderPrice(roomInfo.getPrice());

            //插入订单
            //访问room_info表格，更改对应房间状态（根据日期方面等待学习分布式锁）
           // stringRedisTemplate.delete("roomLock:"+order.getRoomId());


            if(roomInfo.getRoomStatus() == 0){
                stringObjectObjectBoundHashOperations.put(String.valueOf(start),String.valueOf(end));
                int insert = orderMapper.insert(order);
                lock.unlock();
                rocketMQTemplate.syncSend("order-delay:order-delay-tag", MessageBuilder.withPayload(order.getOrderId()).build(),2000,2);
                if(insert == 1){
                    return new Result<>(true,"房间预定成功",order);
                }else {
                    return new Result<>(false,"房间预定失败，请重新尝试");
                }
            }else if(roomInfo.getRoomStatus() == 1){
                lock.unlock();
                return new Result<>(false,"房间已被预订，请重新挑选");
            }else if(roomInfo.getRoomStatus() == 2){
                lock.unlock();
                return new Result<>(false,"房间已下架，请重新挑选");
            }else{
                lock.unlock();
                return new Result<>(false,"房间未上架，请重新挑选");
            }
        }


        //stringRedisTemplate.delete("roomLock:"+order.getRoomId());
        lock.unlock();
        return new Result<>(false,"该房间已有部分时间段被预定,请重新选购！");

    }

    @Override
    public Result<Order> releaseOrder(String orderId) {

        Order order = orderMapper.selectById(orderId);
        if(order.getOrderStatus() == 0){
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
            long start = Long.parseLong(simpleDateFormat.format(order.getStartDate()));
            long end = Long.parseLong(simpleDateFormat.format(order.getLeaveDate()));
            order.setOrderStatus(2);
            orderMapper.updateById(order);

            BoundHashOperations<String, String, String> stringObjectObjectBoundHashOperations = stringRedisTemplate.boundHashOps("roomId:" + order.getRoomId());
            Objects.requireNonNull(stringObjectObjectBoundHashOperations.keys()).forEach(k->{
                if(Long.parseLong(k) == start){
                    if(Long.parseLong(Objects.requireNonNull(stringObjectObjectBoundHashOperations.get(k))) == end){
                        stringObjectObjectBoundHashOperations.delete(k);
                    }
                }
            });
            return new Result(true,"订单取消成功");
        }else if(order.getOrderStatus() == 2){
            return new Result(true,"订单已取消，无需重复提交");
        }else if(order.getOrderStatus() == 1){
            return new Result(false,"订单已支付，请点击申请退款功能");
        }

        return new Result(false,"订单取消失败，请再次重试");
    }
}
